package middleware.p2p.log;

import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

/**
 * 	Classe rappresentante un evento all'interno del sistema di monitoring.
 */
@XmlRootElement(name="monitor_event")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"componentID","vclock","timestamp","queueTotalElements","queueSize"})
public class MiddlewareMonitorEvent implements XmlSerializable{	
	/**
	 * 	Campo necessario alla serializzazione
	 */
	private static final long serialVersionUID = 6129915846132647424L;
	/**
	 * 	ID univoco del componente
	 */
	@XmlElement(name="componentID")
	private String componentID;
	/**
	 *	Vector Clock associato all'evento
	**/
	@XmlElementRef
	private VectorClock vclock;
	/**
	 * 	Timestamp locale dell'evento
	 */
	@XmlElement(name="timestamp")
	private long timestamp;
	/**
	 * 	Numero totale di elementi inseriti nella coda
	 */
	@XmlElement(name="queueTotalElements")
	private int queueTotalElements;
	/**
	 * Dimensione corrente della coda
	 */
	@XmlElement(name="queueSize")
	private int queueSize;
	/**
	 * Stringa XML rappresentante il contenuto della coda
	 */
	@XmlTransient
	private SerializableXmlString queueContent;
	/**
	 * 	Enum che indica a quale coda appartiene lo stato descritto.
	 */
	@XmlTransient
	private QueueType type;
	/**
	 * 	Costruttore principale della classe.
	 * 	@param type					Tipo della coda alla quale associare l'evento
	 * 	@param componentID			ID univoco del componente
	 * 	@param vclock				Vector Clock associato all'evento
	 * 	@param timestamp			Timestamp locale dell'evento
	 * 	@param queueTotalElements	Numero totale di elementi inseriti nella coda
	 * 	@param queueSize			Dimensione corrente della coda	
	 * 	@param queueContent			Stringa XML rappresentante il contenuto della coda
	 */
	public MiddlewareMonitorEvent(QueueType type,String componentID, VectorClock vclock,
			long timestamp, int queueTotalElements, int queueSize,
			SerializableXmlString queueContent) {
		super();
		this.type=type;
		this.componentID = componentID;
		this.vclock = vclock;
		this.timestamp = timestamp;
		this.queueTotalElements = queueTotalElements;
		this.queueSize = queueSize;
		this.queueContent = queueContent;
	}
	/**
	 * 	Costruttore di default della classe. Genera un Evento vuoto.
	 */
	public MiddlewareMonitorEvent() {
		this(QueueType.UNK,null,null,-1,-1,-1,null);
	}
	/**
	 * @return the componentID
	 */
	public String getComponentID() {
		return componentID;
	}
	/**
	 * @param componentID the componentID to set
	 */
	public void setComponentID(String componentID) {
		this.componentID = componentID;
	}
	/**
	 * @return the vclock
	 */
	public VectorClock getVclock() {
		return vclock;
	}
	/**
	 * @param vclock the vclock to set
	 */	
	public void setVclock(VectorClock vclock) {
		this.vclock = vclock;
	}
	/**
	 * @return the timestamp
	 */
	public long getTimestamp() {
		return timestamp;
	}
	/**
	 * @param timestamp the timestamp to set
	 */
	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}
	/**
	 * @return the queueTotalElements
	 */
	public int getQueueTotalElements() {
		return queueTotalElements;
	}
	/**
	 * @return the queueSize
	 */
	public int getQueueSize() {
		return queueSize;
	}
	/**
	 * @return the queueContent
	 */
	@XmlTransient
	public SerializableXmlString getQueueContent() {
		return queueContent;
	}
	/**
	 * @param queueTotalElements the queueTotalElements to set
	 */
	public void setQueueTotalElements(int queueTotalElements) {
		this.queueTotalElements = queueTotalElements;
	}
	/**
	 * @param queueSize the queueSize to set
	 */
	public void setQueueSize(int queueSize) {
		this.queueSize = queueSize;
	}
	/**
	 * @param queueContent the queueContent to set
	 */
	public void setQueueContent(SerializableXmlString queueContent) {
		this.queueContent = queueContent;
	}
	/**
	 * @return the type
	 */
	public QueueType getType() {
		return type;
	}
	/**
	 * @param type the type to set
	 */
	public void setType(QueueType type) {
		this.type = type;
	}
	@Override
	public String toXmlString() {
		try {
			JAXBContext context= JAXBContext.newInstance(this.getClass());
			Marshaller marshaller=context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
			StringWriter sw=new StringWriter();			
			marshaller.marshal(this, sw);
			return sw.toString();
		} catch (JAXBException jaxbe) {
			jaxbe.printStackTrace();
			return "";
		}
	}
	@Override
	public String toString() {
		return "Logging Status Changes on "+this.componentID;
	}
}
